import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.ArrayList;

/**
 *  GUI用户交互界面
 */
public class GUIpractice extends JFrame{
    private static final long serialVersionUID = -8069047189470765958L;
    private JPanel contentPane;
    static final int OP_AMOUNT = 20;
    static final int OP_COLUMN = 5;
    static final int OP_WIDTH = 65;
    static final int ANSWER_WIDTH = 35;
    static final int COMPONET_HEIGHT = 25;
    //设置窗口大小和相关变量的位置

    private JTextField [] tfOp;//放算式的文本域
    private JTextField [] tfAns;//放答案的框

    ArrayList<String> ExerciseList =  new ArrayList<String>();
    ArrayList<String> AnswerList = new ArrayList<String>();
    ArrayList<Boolean> AnswerStatus = new ArrayList<Boolean>();
    private int ExerciseDefaultType = 0;// 默认加减法混合
    private String ExerciseType = "加减混合";
    private boolean  isSubmit = false; // 是否提交
    private boolean isImport = false; // 是否是导入的
    private int totalAmount = 20;
    private int currentPage = 1;
    private int totalPages = 1;
    private int correctAmount;
    private int wrongAmount;
    private double accuracy;
    private double errorrate;


    JToolBar toolBar = new JToolBar();   //导入
    JToolBar toolBar_1 = new JToolBar(); //题目
    JToolBar toolBar_2 = new JToolBar(); // 翻页
    //三个工具栏，对应三个功能组合

    JButton button_7 = new JButton("上一页"); //上一页
    JButton button_8 = new JButton("下一页"); //下一页
    JMenuItem menuItem_5 = new JMenuItem("上一页"); //菜单上一页
    JMenuItem menuItem_6 = new JMenuItem("下一页"); //菜单下一页

    JLabel label = new JLabel("");

    JLabel lblNewLabel = new JLabel("New label");	//当前页数
    JLabel lblNewLabel_1 = new JLabel("New label"); //总页数

    JLabel lblNewLabel_3 = new JLabel("New label"); //状态栏
    JLabel lblNewLabel_4 = new JLabel("New label"); //答案状态栏
    private void showstate(){
        lblNewLabel_3.setText("状态： 当前题目类型:" + ExerciseType + "  题目数量: " + totalAmount + " 题");
    }
    private void showSubmitState(){
        if (!isSubmit){
            lblNewLabel_4.setText("提交之后查看结果！");
        }else{
            String co = String.format("%d", correctAmount);
            String wr = String.format("%d", wrongAmount);
            accuracy = (correctAmount * 1.0 / totalAmount) * 100.0;
            errorrate = (wrongAmount * 1.0 / totalAmount) * 100.0;
            String ac = String.format("%.2f", accuracy);
            ac += '%';
            String er = String.format("%.2f", errorrate);
            er += '%';
            String s = "正确题数 ： " + co + "   " + "错误题数 ： " + wr + "   " +
                    "正确率  : " + ac + "   " + "错误率 : " + er;
            lblNewLabel_4.setText(s);
        }
    }
    private void reachFirst(){
        if (currentPage == 1){
            button_7.setEnabled(false);
            menuItem_5.setEnabled(false);
        }else{
            button_7.setEnabled(true);
            menuItem_5.setEnabled(true);
        }
    }
    private void reachLast(){
        if (currentPage == totalPages){
            button_8.setEnabled(false);
            menuItem_6.setEnabled(false);
        }else{
            button_8.setEnabled(true);
            menuItem_6.setEnabled(true);
        }
    }
    private void prePage(){
        saveCurrentPageAnswer();
        this.currentPage--;
        showCurrentPageExer();
        reachFirst();
        reachLast();
    }
    private void nextPage(){
        saveCurrentPageAnswer();
        this.currentPage++;
        showCurrentPageExer();
        reachLast();
        reachFirst();
    }
    private void saveCurrentPageAnswer(){
        int ansIndex = 0;
        for (int i = (currentPage-1) * OP_AMOUNT;i < currentPage*OP_AMOUNT;i++){
            AnswerList.set(i,tfAns[ansIndex].getText().trim());
            ansIndex++;
        }
    }
    public void showCurrentPageExer(){
        int btnIndex = 0 ;
        for(int i=(currentPage-1)*OP_AMOUNT; i<currentPage*OP_AMOUNT; i++){
            if (i == ExerciseList.size()){break;}
            tfOp[btnIndex].setText(ExerciseList.get(i)+"=");
            if (!isSubmit){ tfAns[btnIndex].setBackground(Color.WHITE);}
            else{
                if (AnswerStatus.get(i)){ tfAns[btnIndex].setBackground(Color.GREEN);}
                else{ tfAns[btnIndex].setBackground(Color.RED);}
            }
            tfAns[btnIndex].setText(AnswerList.get(i));
            btnIndex ++ ;
        }
    }
    private void showPages(){
        lblNewLabel.setText("当前页数:" + currentPage);
        this.totalPages = (int) Math.ceil(totalAmount / OP_AMOUNT);
        lblNewLabel_1.setText("总页数:" + totalPages);
    }
    private  void initExerciseComponents(){
        tfOp = new JTextField[OP_AMOUNT];
        tfAns = new JTextField[OP_AMOUNT];
        //生成对应数目的算式位置和答案位置
        for (int i = 0; i < OP_AMOUNT; i++) {
            //循环加入算式和答案，配对加入
            tfOp[i] = new JTextField();
            tfOp[i].setBounds(20 + (i % OP_COLUMN) * (OP_WIDTH + ANSWER_WIDTH + 5),
                    50 + (i / OP_COLUMN) * (COMPONET_HEIGHT + 10),
                    OP_WIDTH, COMPONET_HEIGHT);
            //设置算式框的位置和大小，位置遵循一定的规律
            tfOp[i].setHorizontalAlignment(JTextField.RIGHT);
            //设置算式框里面的算式为右对齐
            tfOp[i].setEditable(false);//算式位置是不可更改的
            contentPane.add(tfOp[i]);

            tfAns[i] = new JTextField();
            tfAns[i].setBounds(20 + (i % OP_COLUMN) * (OP_WIDTH + ANSWER_WIDTH + 5) + OP_WIDTH,
                    50 + (i / OP_COLUMN) * (COMPONET_HEIGHT + 10),
                    ANSWER_WIDTH,
                    COMPONET_HEIGHT);
            tfAns[i].setEditable(true);
            contentPane.add(tfAns[i]);
        }
        showPages();
        showstate();
        showSubmitState();
    }
    private void updateExerciseComponents(int totalAmount,int ExerciseType,
                                          int currentPage,boolean getNew,boolean clearAnswers,boolean clearExercise){
        if (clearAnswers)  {AnswerList.clear();}
        if (clearExercise) { ExerciseList.clear();}
        if  (isImport){
            this.ExerciseType = "加减混合";
            showstate();
            showPages();
            isImport = false;
        }
        AnswerStatus.clear();
        Exercise exercise = new Exercise();
        FileOperation.willCreate();
        if (getNew){
            for (int i = 0 ; i < totalAmount ; i ++){
                String oneExercise = ExerciseType == -1?exercise.showOneSubPoeration():
                        ExerciseType == 0?exercise.showOneMixPoeration():
                                exercise.showOneAddPoeration();
                ExerciseList.add(oneExercise);
                AnswerList.add("");
            }
        }
        showCurrentPageExer();
        showPages();
        showstate();
        showSubmitState();
        reachFirst();
        reachLast();
    }
    private void judge(){
        Judgement judgement = new Judgement();
        correctAmount = wrongAmount = 0;
        for (int i = 0 ; i < totalAmount ; i++){
            if (String.valueOf(judgement.calculate(ExerciseList.get(i))).equals(AnswerList.get(i))){
                correctAmount++;
                AnswerStatus.add(true);
            }else{
                wrongAmount++;
                AnswerStatus.add(false);
            }
        }
        showSubmitState();
    }
    private void importExercise(){
        ExerciseList.clear();
        AnswerStatus.clear();
        AnswerList.clear();
        JFileChooser jfc = new JFileChooser();//新建一个文件选择器
        jfc.showOpenDialog(null);//设置参数的值可以改变文件选择器在屏幕上的弹出位置
        File file = jfc.getSelectedFile();
        try {
            if (!file.getName().contains(".txt")){
                JOptionPane.showMessageDialog(null, "只能导入txt文件！"
                        ,"提示",JOptionPane.INFORMATION_MESSAGE);return;}
            FileOperation.read(ExerciseList, String.valueOf(file.toPath()));
            for (int i = 0 ; i < ExerciseList.size() ; i++) {AnswerList.add("");}
            this.totalAmount = ExerciseList.size();
            this.lblNewLabel_3.setText("读入文件" + file.getName());
            JOptionPane.showMessageDialog(null, "导入题目成功！"
                    ,"提示",JOptionPane.INFORMATION_MESSAGE);
            showPages();
            showCurrentPageExer();
            reachFirst();
            reachLast();
        }catch (Exception e){
            JOptionPane.showMessageDialog(null, "导入题目失败！"
                    ,"提示",JOptionPane.INFORMATION_MESSAGE);
        }
    }
    private void exportExercise(){
        JFileChooser jfc = new JFileChooser();
        jfc.showOpenDialog(null);
        try {
            File file = jfc.getSelectedFile();
            ExerciseList.forEach(exercise ->{
                FileOperation.save(exercise+",",file.getPath());
            });
            JOptionPane.showMessageDialog(null, "导出题目成功！"
                    ,"提示",JOptionPane.INFORMATION_MESSAGE);
        }catch (Exception e){
            JOptionPane.showMessageDialog(null, "导出题目失败！"
                    ,"提示",JOptionPane.INFORMATION_MESSAGE);
        }

    }
    public  GUIpractice(){
        //可视化窗口编辑GUI界面，添加对应的动作监听
        setTitle("100以内算式速算");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 570, 376);

        JMenuBar menuBar = new JMenuBar();
        setJMenuBar(menuBar);

        JMenu menu = new JMenu("文件");
        menuBar.add(menu);

        JMenuItem menuItem = new JMenuItem("导入");
        menu.add(menuItem);

        menuItem.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                importExercise();
            }
        });

        JMenuItem menuItem_1 = new JMenuItem("导出");
        menu.add(menuItem_1);

        menuItem_1.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                exportExercise();
            }
        });

        JMenu menu_1 = new JMenu("题目设置");
        menuBar.add(menu_1);

        JMenu menuItem_7 = new JMenu("根据类型生成");
        menu_1.add(menuItem_7);

        JCheckBoxMenuItem chckbxmntmadd = new JCheckBoxMenuItem("加法题目");
        menuItem_7.add(chckbxmntmadd);
        chckbxmntmadd.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                ExerciseDefaultType = 1;
                ExerciseType = "加法算式";
                updateExerciseComponents(totalAmount,ExerciseDefaultType,1,true,true,true);
                showstate();
            }
        });

        JCheckBoxMenuItem chckbxmntmsub = new JCheckBoxMenuItem("减法题目");
        menuItem_7.add(chckbxmntmsub);

        chckbxmntmsub.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                ExerciseDefaultType = -1;
                ExerciseType = "减法算式";
                updateExerciseComponents(totalAmount,ExerciseDefaultType,1,true,true,true);
                showstate();
            }
        });

        JCheckBoxMenuItem chckbxmntmas = new JCheckBoxMenuItem("加减混合");
        menuItem_7.add(chckbxmntmas);

        chckbxmntmas.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                ExerciseDefaultType = 0;
                ExerciseType = "加减混合";
                updateExerciseComponents(totalAmount,ExerciseDefaultType,1,true,true,true);
                showstate();
            }
        });

        JMenu menuItem_8 = new JMenu("根据数量生成");
        menu_1.add(menuItem_8);

        JCheckBoxMenuItem checkBoxMenuItem_3 = new JCheckBoxMenuItem("20");
        menuItem_8.add(checkBoxMenuItem_3);

        checkBoxMenuItem_3.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                totalAmount = 20;
                updateExerciseComponents(totalAmount,ExerciseDefaultType,1,true,true,true);
            }
        });

        JCheckBoxMenuItem checkBoxMenuItem_4 = new JCheckBoxMenuItem("40");
        menuItem_8.add(checkBoxMenuItem_4);

        checkBoxMenuItem_4.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                totalAmount = 40;
                updateExerciseComponents(totalAmount,ExerciseDefaultType,1,true,true,true);
            }
        });

        JCheckBoxMenuItem checkBoxMenuItem_5 = new JCheckBoxMenuItem("100");
        menuItem_8.add(checkBoxMenuItem_5);

        checkBoxMenuItem_5.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                totalAmount = 100;
                updateExerciseComponents(totalAmount,ExerciseDefaultType,1,true,true,true);
            }
        });

        JMenu menu_2 = new JMenu("题目操作");
        menuBar.add(menu_2);

        JMenuItem menuItem_2 = new JMenuItem("重新生成");
        menu_2.add(menuItem_2);

        menuItem_2.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                isSubmit = false;
                updateExerciseComponents(totalAmount,ExerciseDefaultType,currentPage,true,true,true);
            }
        });

        JMenuItem menuItem_3 = new JMenuItem("清空");
        menu_2.add(menuItem_3);

        menuItem_3.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                AnswerStatus.clear();
                for (int i = 0 ; i<AnswerList.size();i++){AnswerList.set(i,"");}
                for (int i = 0;i<OP_AMOUNT;i++){tfAns[i].setText("");}
                isSubmit = false;
                showSubmitState();
                showCurrentPageExer();
            }
        });

        JMenuItem menuItem_4 = new JMenuItem("提交");
        menu_2.add(menuItem_4);

        menuItem_4.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                isSubmit = true;
                saveCurrentPageAnswer();
                judge();
                showSubmitState();
                showCurrentPageExer();
            }
        });

        JMenu menu_3 = new JMenu("查看");
        menuBar.add(menu_3);


        menu_3.add(menuItem_5);

        menuItem_5.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent arg0) { prePage(); }

        });

        menu_3.add(menuItem_6);

        menuItem_6.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent arg0) {nextPage();}

        });

        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);

        JLabel lblNewLabel_2 = new JLabel("New label");

        lblNewLabel_2.setText("------------------------------------------"
                + "------------------------------------------"
                + "-----------------------------------------------------");

        GroupLayout gl_contentPane = new GroupLayout(contentPane);
        gl_contentPane.setHorizontalGroup(
                gl_contentPane.createParallelGroup(GroupLayout.Alignment.LEADING)
                        .addGroup(gl_contentPane.createSequentialGroup()
                                .addGroup(gl_contentPane.createParallelGroup(GroupLayout.Alignment.LEADING)
                                        .addGroup(gl_contentPane.createSequentialGroup()
                                                .addComponent(toolBar, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                                                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                                                .addComponent(toolBar_1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                                                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                                                .addComponent(toolBar_2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
                                        .addGroup(gl_contentPane.createSequentialGroup()
                                                .addGap(137)
                                                .addGroup(gl_contentPane.createParallelGroup(GroupLayout.Alignment.LEADING)
                                                        .addGroup(gl_contentPane.createSequentialGroup()
                                                                .addGap(63)
                                                                .addComponent(lblNewLabel)
                                                                .addGap(42)
                                                                .addComponent(lblNewLabel_1))
                                                        .addComponent(label)))
                                        .addComponent(lblNewLabel_2)
                                        .addGroup(gl_contentPane.createSequentialGroup()
                                                .addContainerGap()
                                                .addComponent(lblNewLabel_3))
                                        .addGroup(gl_contentPane.createSequentialGroup()
                                                .addContainerGap()
                                                .addComponent(lblNewLabel_4)))
                                .addContainerGap(GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        gl_contentPane.setVerticalGroup(
                gl_contentPane.createParallelGroup(GroupLayout.Alignment.TRAILING)
                        .addGroup(gl_contentPane.createSequentialGroup()
                                .addGroup(gl_contentPane.createParallelGroup(GroupLayout.Alignment.LEADING)
                                        .addComponent(toolBar, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                                        .addComponent(toolBar_1, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)
                                        .addComponent(toolBar_2, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE))
                                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, 169, Short.MAX_VALUE)
                                .addComponent(label)
                                .addGap(13)
                                .addGroup(gl_contentPane.createParallelGroup(GroupLayout.Alignment.BASELINE)
                                        .addComponent(lblNewLabel_1)
                                        .addComponent(lblNewLabel))
                                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(lblNewLabel_2)
                                .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(lblNewLabel_3)
                                .addPreferredGap(LayoutStyle.ComponentPlacement.UNRELATED)
                                .addComponent(lblNewLabel_4)
                                .addGap(19))
        );


        button_7.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent arg0) { prePage(); }
        });

        toolBar_2.add(button_7);

        button_8.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                nextPage();
            }
        });
        toolBar_2.add(button_8);

        JButton button_4 = new JButton("重新生成");
        button_4.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                isSubmit = false;
                updateExerciseComponents(totalAmount,ExerciseDefaultType,currentPage,true,true,true);
            }
        });
        toolBar_1.add(button_4);

        JButton button = new JButton("清空");
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                AnswerStatus.clear();
                for (int i = 0 ; i<AnswerList.size();i++){AnswerList.set(i,"");}
                for (int i = 0;i<OP_AMOUNT;i++){tfAns[i].setText("");}
                isSubmit = false;
                showSubmitState();
                showCurrentPageExer();
            }
        });
        toolBar_1.add(button);

        JButton button_6 = new JButton("提交");
        button_6.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                isSubmit = true;
                saveCurrentPageAnswer();
                judge();
                showSubmitState();
                showCurrentPageExer();
            }
        });
        toolBar_1.add(button_6);

        JButton button_2 = new JButton("导入");
        button_2.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                importExercise();
            }
        });
        toolBar.add(button_2);

        JButton button_3 = new JButton("导出");
        button_3.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                exportExercise();
            }
        });
        toolBar.add(button_3);
        contentPane.setLayout(gl_contentPane);
        initExerciseComponents();
        updateExerciseComponents(totalAmount,ExerciseDefaultType,1,true,true,true);
    }
}
